  var fs = require('fs');
  var path = require('path');
  var hogan = require('hogan.js');

  var hoganTemplates = require('./templates/diff2html-templates.js');

  var extraTemplates;

  export function HoganJsUtils(configuration) {
    let config = configuration || {};
    let extraTemplates = config.templates || {};

    var rawTemplates = config.rawTemplates || {};
    for (var templateName in rawTemplates) {
      if (rawTemplates.hasOwnProperty(templateName)) {
        if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]);
      }
    }


    return {
      
      render: function (namespace, view, params) {
        var template = this.template(namespace, view);
        if (template) {
          return template.render(params);
        }

        return null;
      },

      template: function (namespace, view) {
        var templateKey = this._templateKey(namespace, view);

        return this._getTemplate(templateKey);
      },

      _getTemplate: function (templateKey) {
        var template;

        if (!config.noCache) {
          template = this._readFromCache(templateKey);
        }

        if (!template) {
          template = this._loadTemplate(templateKey);
        }

        return template;
      },

      _loadTemplate: function (templateKey) {
        var template;

        try {
          if (fs.readFileSync) {
            var templatesPath = path.resolve(__dirname, 'templates');
            var templatePath = path.join(templatesPath, templateKey);
            var templateContent = fs.readFileSync(templatePath + '.mustache', 'utf8');
            template = hogan.compile(templateContent);
            hoganTemplates[templateKey] = template;
          }
        } catch (e) {
          console.error('Failed to read (template: ' + templateKey + ') from fs: ' + e.message);
        }

        return template;
      },

      _readFromCache: function (templateKey) {
        return extraTemplates[templateKey] || hoganTemplates[templateKey];
      },

      _templateKey: function (namespace, view) {
        return namespace + '-' + view;
      },

      compile: function (templateStr) {
        return hogan.compile(templateStr);
      }
    }
  }
